<template>
  <div class="monitor-container">
    <div class="content-area">
      <div class="monitor-grid">
        <!-- 上方设备卡片 -->
        <div class="device-card top">
          <TempCard 
            :sensor="sensors[0]" 
            :history-data="sensorHistoryCache.get(sensors[0]?.sensorId) || []"
            :ref="sensors[0] ? `sensorComponent_${sensors[0].sensorId}` : ''"
          />
        </div>

        <!-- 左侧设备卡片 -->
        <div class="device-card left">
          <TempHumCard 
            :sensor="sensors[1]" 
            :history-data="sensorHistoryCache.get(sensors[1]?.sensorId) || []"
            :ref="sensors[1] ? `sensorComponent_${sensors[1].sensorId}` : ''"
          />
        </div>

        <!-- 中间地图区域 -->
        <div class="map-area">
          <div class="export-controls" v-if="selectedNurseryId">
            <el-select v-model="selectedTimeRange" placeholder="选择时间范围" @change="handleTimeRangeChange">
              <el-option v-for="item in timeRangeOptions" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
            <el-date-picker
              v-if="showDatePicker"
              v-model="dateRange"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              value-format="timestamp"
              style="width: 300px; margin-left: 10px;"
            />
            <el-button type="primary" @click="exportToExcel" :loading="exporting" style="margin-left: 10px;">导出Excel</el-button>
          </div>
          <NurseryMap 
            ref="nurseryMap"
            :nurseries="nurseries"
            @select="handleNurserySelect"
            :key="selectedNurseryId"
          />
        </div>

        <!-- 右侧设备卡片 -->
        <div class="device-card right">
          <TempHumCard 
            :sensor="sensors[2]" 
            :history-data="sensorHistoryCache.get(sensors[2]?.sensorId) || []"
            :ref="sensors[2] ? `sensorComponent_${sensors[2].sensorId}` : ''"
          />
        </div>

        <!-- 下方设备卡片 -->
        <div class="device-card bottom">
          <TempCard 
            :sensor="sensors[3]" 
            :history-data="sensorHistoryCache.get(sensors[3]?.sensorId) || []"
            :ref="sensors[3] ? `sensorComponent_${sensors[3].sensorId}` : ''"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import request from '@/utils/request'
import TempCard from '@/components/TempCard.vue'
import TempHumCard from '@/components/TempHumCard.vue'
import NurseryMap from '@/components/NurseryMap.vue'
import * as XLSX from 'xlsx'

export default {
  name: 'MonitorView',
  components: {
    TempCard,
    TempHumCard,
    NurseryMap
  },
  data() {
    return {
      sensors: [], // 设备列表
      loading: false, // 加载状态
      sensorHistoryCache: new Map(), // 缓存不同设备的历史数据
      nurseries: [], // 育苗点列表
      selectedNurseryId: null, // 当前选择的育苗点ID
      lastUpdateTime: null, // 最后更新时间
      selectedTimeRange: '1', // 默认选择最近一天
      exporting: false, // 导出状态
      timeRangeOptions: [
        { label: '最近一天', value: '1' },
        { label: '最近一周', value: '7' },
        { label: '最近一个月', value: '30' },
        { label: '自定义日期范围', value: 'custom' }
      ],
      autoRefreshTimer: null, // 自动刷新定时器
      refreshInterval: 15 * 60 * 1000, // 刷新间隔，15分钟
      isAutoRefreshing: false, // 是否正在自动刷新
      dateRange: [], // 自定义日期范围
      showDatePicker: false // 是否显示日期选择器
    }
  },
  mounted() {
    // 获取育苗点数据
    this.fetchNurseries()
    
    // 初始化自动刷新
    this.startAutoRefresh()
  },
  beforeDestroy() {
    // 组件销毁前清除定时器
    this.stopAutoRefresh()
  },
  methods: {
    // 获取设备最新记录
    async fetchLatestRecord(sensorId) {
      try {
        const response = await request({
          url: `/sensors/latest-record/${sensorId}`,
          method: 'get'
        })
        
        const sensor = this.sensors.find(s => s.sensorId === sensorId)
        if (sensor) {
          sensor.currentRecord = response
        }
      } catch (error) {
        console.error(`获取设备${sensorId}最新记录失败:`, error)
      }
    },

    // 获取设备历史数据
    async fetchSensorHistory(sensorId) {
      try {
        let startTime, endTime = new Date()
        
        if (this.selectedTimeRange === 'custom' && this.dateRange.length === 2) {
          // 使用自定义日期范围
          startTime = new Date(this.dateRange[0])
          endTime = new Date(this.dateRange[1])
        } else {
          // 使用预设时间范围
          const days = parseInt(this.selectedTimeRange) || 1
          startTime = new Date(endTime - days * 24 * 60 * 60 * 1000)
        }
        
        const response = await request({
          url: `/sensors/records/${sensorId}`,
          method: 'get',
          params: {
            startTime: startTime.getTime(),
            endTime: endTime.getTime()
          }
        })
        
        this.sensorHistoryCache.set(sensorId, response)
      } catch (error) {
        console.error(`获取设备${sensorId}历史数据失败:`, error)
      }
    },

    // 获取育苗点列表
    async fetchNurseries() {
      try {
        // 1. 获取育苗点基本信息
        const response = await request({
          url: '/departments/page',
          method: 'get',
          params: {
            current: 1,
            size: 10,
            deptType: 4
          }
        })
        
        // 2. 获取育苗点地理位置信息
        const deptIds = response.records.map(dept => dept.deptId)
        const locationResponse = await request({
          url: '/department-locations/batch',
          method: 'post',
          data: deptIds
        })
        
        // 3. 整合数据
        this.nurseries = locationResponse.map(nursery => ({
          id: nursery.deptId,
          name: nursery.deptName,
          address: nursery.address,
          longitude: nursery.longitude,
          latitude: nursery.latitude,
          altitude: nursery.altitude
        }))
      } catch (error) {
        console.error('获取育苗点列表失败:', error)
        this.$message.error('获取育苗点列表失败')
      }
    },

    // 处理育苗点选择
    async handleNurserySelect(nurseryId) {
      if (this.selectedNurseryId === nurseryId) return
      
      this.selectedNurseryId = nurseryId
      this.loading = true
      
      try {
        // 1. 获取所有设备
        const response = await request({
          url: '/sensors',
          method: 'get'
        })
        
        // 2. 过滤出属于当前育苗点的设备
        const nurseryDevices = response.filter(sensor => sensor.cultivateId === nurseryId)
        
        // 3. 按照capability分类设备
        const tempHumDevices = nurseryDevices.filter(sensor => sensor.capability === 2) // 温湿度设备
        const tempDevices = nurseryDevices.filter(sensor => sensor.capability === 1)    // 单温度设备
        
        // 4. 重新排序设备列表，使温湿度设备在左右两侧，单温度设备在上下两侧
        this.sensors = [
          tempDevices[0] || null,    // top    - 单温度
          tempHumDevices[0] || null, // left   - 温湿度
          tempHumDevices[1] || null, // right  - 温湿度
          tempDevices[1] || null     // bottom - 单温度
        ]
        
        // 5. 只为有效的设备获取数据
        await this.fetchSensorData()
        
        // 6. 重置自动刷新
        this.restartAutoRefresh()
      } catch (error) {
        console.error('获取设备数据失败:', error)
        this.$message.error('获取设备数据失败')
      } finally {
        this.loading = false
      }
    },

    // 获取设备数据（抽取为单独方法，便于时间范围变化时重新获取）
    async fetchSensorData() {
      const validSensors = this.sensors.filter(sensor => sensor !== null)
      if (validSensors.length > 0) {
        await Promise.all([
          ...validSensors.map(sensor => this.fetchLatestRecord(sensor.sensorId)),
          ...validSensors.map(sensor => this.fetchSensorHistory(sensor.sensorId))
        ])
        
        // 强制更新视图
        this.$forceUpdate()
        this.$nextTick(() => {
          // 更新地图标记
          this.$refs.nurseryMap?.updateNurseryMarkers()
        })
      } else {
        this.$message.warning('该育苗点暂无设备数据')
      }
    },

    // 导出Excel
    async exportToExcel() {
      if (!this.selectedNurseryId) {
        this.$message.warning('请先选择育苗点')
        return
      }

      const validSensors = this.sensors.filter(sensor => sensor !== null)
      if (validSensors.length === 0) {
        this.$message.warning('没有可导出的设备数据')
        return
      }
      
      if (this.selectedTimeRange === 'custom' && (!this.dateRange || this.dateRange.length !== 2)) {
        this.$message.warning('请选择完整的日期范围')
        return
      }

      this.exporting = true
      try {
        // 确保数据是最新的
        await this.fetchSensorData()
        
        // 获取选中的育苗点信息
        const selectedNursery = this.nurseries.find(n => n.id === this.selectedNurseryId)
        
        // 获取时间范围信息
        let startTime, endTime
        
        if (this.selectedTimeRange === 'custom' && this.dateRange.length === 2) {
          // 使用自定义日期范围
          startTime = new Date(this.dateRange[0])
          endTime = new Date(this.dateRange[1])
        } else {
          // 使用预设时间范围
          endTime = new Date()
          const days = parseInt(this.selectedTimeRange)
          startTime = new Date(endTime - days * 24 * 60 * 60 * 1000)
        }
        
        // 格式化时间范围字符串
        const formatDate = (date) => {
          return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`
        }
        const timeRangeStr = `${formatDate(startTime)}至${formatDate(endTime)}`
        
        // 创建工作簿和工作表
        const wb = XLSX.utils.book_new()
        
        // 构建表头和数据
        const headers = ['时间']
        validSensors.forEach(sensor => {
          if (sensor.capability === 1) { // 温度设备
            headers.push(`${sensor.sensorName || '未命名设备'}-温度(°C)`)
          } else if (sensor.capability === 2) { // 温湿度设备
            headers.push(`${sensor.sensorName || '未命名设备'}-温度(°C)`)
            headers.push(`${sensor.sensorName || '未命名设备'}-湿度(%)`)
          }
        })
        
        // 合并所有时间点
        const allTimestamps = new Set()
        validSensors.forEach(sensor => {
          const historyData = this.sensorHistoryCache.get(sensor.sensorId) || []
          historyData.forEach(record => {
            allTimestamps.add(record.recordTime)
          })
        })
        
        // 按时间排序
        const sortedTimestamps = Array.from(allTimestamps).sort()
        
        // 构建数据行
        const rows = sortedTimestamps.map(timestamp => {
          const row = [new Date(timestamp).toLocaleString()]
          
          validSensors.forEach(sensor => {
            const historyData = this.sensorHistoryCache.get(sensor.sensorId) || []
            const record = historyData.find(r => r.recordTime === timestamp)
            
            if (sensor.capability === 1) { // 温度设备
              row.push(record ? record.temperature : '')
            } else if (sensor.capability === 2) { // 温湿度设备
              row.push(record ? record.temperature : '')
              row.push(record ? record.humidity : '')
            }
          })
          
          return row
        })
        
        // 添加标题行
        const title = [`育苗点: ${selectedNursery.name}`, `时间范围: ${timeRangeStr}`]
        const data = [title, [], headers, ...rows]
        
        // 创建工作表
        const ws = XLSX.utils.aoa_to_sheet(data)
        
        // 设置列宽
        const wscols = [{ wch: 20 }]
        for (let i = 1; i < headers.length; i++) {
          wscols.push({ wch: 15 })
        }
        ws['!cols'] = wscols
        
        // 添加工作表到工作簿
        XLSX.utils.book_append_sheet(wb, ws, '设备监测数据')
        
        // 生成文件名
        const fileName = `${selectedNursery.name}_监测数据_${timeRangeStr}.xlsx`
        
        // 导出文件
        XLSX.writeFile(wb, fileName)
        
        this.$message.success('导出成功')
      } catch (error) {
        console.error('导出Excel失败:', error)
        this.$message.error('导出Excel失败')
      } finally {
        this.exporting = false
      }
    },

    // 开始自动刷新
    startAutoRefresh() {
      if (this.autoRefreshTimer) return
      
      this.autoRefreshTimer = setInterval(() => {
        if (this.selectedNurseryId) {
          this.refreshLatestData()
        }
      }, this.refreshInterval)
      
      console.log('数据自动刷新已启动，间隔：15分钟')
    },
    
    // 停止自动刷新
    stopAutoRefresh() {
      if (this.autoRefreshTimer) {
        clearInterval(this.autoRefreshTimer)
        this.autoRefreshTimer = null
        console.log('数据自动刷新已停止')
      }
    },
    
    // 重启自动刷新
    restartAutoRefresh() {
      this.stopAutoRefresh()
      this.startAutoRefresh()
    },
    
    // 刷新最新数据
    async refreshLatestData() {
      if (this.isAutoRefreshing || !this.selectedNurseryId) return
      
      this.isAutoRefreshing = true
      const validSensors = this.sensors.filter(sensor => sensor !== null)
      
      try {
        console.log('正在刷新传感器数据...')
        
        for (const sensor of validSensors) {
          // 获取最新记录
          const latestResponse = await request({
            url: `/sensors/latest-record/${sensor.sensorId}`,
            method: 'get'
          })
          
          if (latestResponse) {
            // 更新传感器当前记录
            sensor.currentRecord = latestResponse
            
            // 从缓存中获取历史数据
            const historyData = this.sensorHistoryCache.get(sensor.sensorId) || []
            
            // 检查是否是新数据
            const isNewRecord = !historyData.some(record => 
              record.recordTime === latestResponse.recordTime
            )
            
            // 如果是新数据，添加到历史记录中
            if (isNewRecord && latestResponse.recordTime) {
              historyData.push(latestResponse)
              // 按时间排序
              historyData.sort((a, b) => a.recordTime - b.recordTime)
              
              // 根据选择的时间范围，维护历史数据长度
              let timeLimit
              
              if (this.selectedTimeRange === 'custom' && this.dateRange.length === 2) {
                // 使用自定义日期范围
                timeLimit = this.dateRange[0]
              } else {
                // 使用预设时间范围
                const now = new Date().getTime()
                const days = parseInt(this.selectedTimeRange) || 1
                timeLimit = now - days * 24 * 60 * 60 * 1000
              }
              
              // 移除超出时间范围的数据
              const filteredData = historyData.filter(record => 
                record.recordTime >= timeLimit
              )
              
              // 更新缓存
              this.sensorHistoryCache.set(sensor.sensorId, filteredData)
            }
          }
        }
        
        // 更新最后刷新时间
        this.lastUpdateTime = new Date().toLocaleString()
        console.log('数据刷新完成：', this.lastUpdateTime)
        
        // 将缓存的最新数据传递给组件
        this.$nextTick(() => {
          // 在下一个渲染周期更新组件
          validSensors.forEach(sensor => {
            if (sensor) {
              // 确保子组件能接收到更新后的数据
              const historyData = this.sensorHistoryCache.get(sensor.sensorId) || []
              const componentRefs = this.$refs[`sensorComponent_${sensor.sensorId}`]
              if (componentRefs && componentRefs.updateData) {
                componentRefs.updateData(sensor, historyData)
              }
            }
          })
          
          // 强制更新视图
          this.$forceUpdate()
        })
      } catch (error) {
        console.error('自动刷新数据失败:', error)
      } finally {
        this.isAutoRefreshing = false
      }
    },

    // 处理时间范围变化
    handleTimeRangeChange(value) {
      this.showDatePicker = value === 'custom'
      
      if (value !== 'custom' && this.selectedNurseryId) {
        this.fetchSensorData()
      }
    }
  },
  watch: {
    // 监听时间范围变化，重新获取数据
    selectedTimeRange() {
      if (this.selectedNurseryId && this.selectedTimeRange !== 'custom') {
        this.fetchSensorData()
      }
    },
    // 监听日期范围变化，重新获取数据
    dateRange() {
      if (this.selectedNurseryId && this.selectedTimeRange === 'custom' && this.dateRange.length === 2) {
        this.fetchSensorData()
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.monitor-container {
  background-color: #f5f7fa;
  height: 100vh; // 容器占满整个视口高度
  display: flex;
  flex-direction: column;

  .content-area {
    flex: 1; // 占满除去其他元素后的剩余空间
    background-color: #fff;
    padding: 10px;
    border-radius: 4px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }

  .export-controls {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 10;
    display: flex;
    align-items: center;
    background-color: rgba(255, 255, 255, 0.9);
    padding: 8px 12px;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    
    .el-select {
      width: 120px;
      margin-right: 10px;
    }
  }

  .monitor-grid {
    flex: 1; // 占满content-area的剩余空间
    display: grid;
    // 定义网格区域布局：
    // left区域占据左侧整列
    // top区域占据中间上部
    // map区域占据中间中部
    // bottom区域占据中间下部
    // right区域占据右侧整列
    grid-template-areas: 
      "left top right"
      "left map right"
      "left bottom right";
    grid-template-columns: 30% 1fr 30%; // 左右两侧各占25%，中间自适应
    grid-template-rows: 35% 1fr 35%;    // 上下各占30%，中间自适应
    gap: 20px; // 卡片之间的间距
    min-height: 0; // 防止grid内容溢出
  }

  .device-card {
    position: relative;
    background-color: rgba(255, 255, 255, 0.9);
    border-radius: 8px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    backdrop-filter: blur(10px);
    transition: all 0.3s ease;
    overflow: auto;

    &:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.15);
    }

    // 定义各个卡片所在的网格区域
    &.top { 
      grid-area: top; // 对应grid-template-areas中的top区域
    }
    &.left { 
      grid-area: left; // 对应grid-template-areas中的left区域
      grid-row: 1 / -1; // 从第一行延伸到最后一行
    }
    &.right { 
      grid-area: right; // 对应grid-template-areas中的right区域
      grid-row: 1 / -1; // 从第一行延伸到最后一行
    }
    &.bottom { 
      grid-area: bottom; // 对应grid-template-areas中的bottom区域
    }
  }

  .map-area {
    grid-area: map; // 对应grid-template-areas中的map区域
    position: relative;
  }
}
</style>
